#include "sqlpool.h"
#include "thread_pool.h"
/*创建连接池*/
SQL_CONN_POOL *sql_pool_create(int connect_pool_number, const char ip[], int port,
                               const char db_name[], const char user[], const char passwd[])
{
   SQL_CONN_POOL *sp = NULL;
   if (connect_pool_number < 1)
   {
      printf("connect_pool_number < 1. defalut 1 \n");
      connect_pool_number = 1;
   }
   if ((sp=(SQL_CONN_POOL *)calloc(1, sizeof(SQL_CONN_POOL))) == NULL)
   {
      printf("malloc SQL_CONN_POOL error.\n");
      return NULL;
   }

   //初始化
   sp->shutdown    = 0; //开启连接池
   sp->pool_number = 0;
   sp->busy_number = 0; //正在使用连接数
   strcpy(sp->ip, ip);
   sp->port = port;
   strcpy(sp->db_name, db_name);
   strcpy(sp->user, user);
   strcpy(sp->passwd, passwd);

   /*创建连接*/
   if (connect_pool_number > POOL_MAX_NUMBER)
   {
       connect_pool_number = POOL_MAX_NUMBER;
   }

   for (int index = 0; index < connect_pool_number; index++)
   {
      //创建失败
      if (0 != create_db_connect(sp, &sp->sql_pool[index]))
      {
         //销毁连接池
         sql_pool_destroy(sp);
         return NULL;
      }
      //创建成功
      sp->sql_pool[index].index = index;
      sp->pool_number++;
      printf("create database pool connect:-%d-.\n",sp->sql_pool[index].index); 
   }

   return sp;
}

/*节点创建连接*/
int create_db_connect(SQL_CONN_POOL *sp, SQL_NODE *node)
{
   int res=0; //0正常 -1初始化失败 1 连接失败

 do
 {
   if (sp->shutdown == 1) //线程池关闭状态
   { 
      return -1;
   }
   /*加锁*/
   pthread_mutex_init(&node->lock, NULL);

   /*初始化mysql对象*/
   if (NULL == mysql_init(&node->fd))
   {
     printf("mysql init error. \n");
     res = -1;
     break;
   }

   /*连接失败*/
   if (!(node->mysql_sock = mysql_real_connect(
        &node->fd, sp->ip, sp->user, sp->passwd, sp->db_name, sp->port, NULL, 0)))
   {
     printf("can not connect to mysql.\n");
     node->sql_state = DB_DISCONN;
     res = 1;
     break;
   }

   /*连接成功*/
   node->used = 0;
   node->sql_state = DB_CONN;

   //设置连接超时时间为3s，3s未连接成功则超时
   int opt = 3;
   mysql_options(&node->fd, MYSQL_OPT_CONNECT_TIMEOUT, &opt);
   res = 0;

 }while(0);

 return res;
}

/*销毁连接池*/
void sql_pool_destroy(SQL_CONN_POOL *sp)
{
  printf("destroy sql pool ... ... \n");

  sp->shutdown = 1; //关闭连接池
  for (int index = 0; index < sp->pool_number; index++)
  {
     if (NULL != sp->sql_pool[index].mysql_sock)
     {
        mysql_close(sp->sql_pool[index].mysql_sock);
        sp->sql_pool[index].mysql_sock = NULL;
     }
     sp->sql_pool[index].sql_state = DB_DISCONN; 
     sp->pool_number--;
  }
}

/*取出一个未使用的连接*/
SQL_NODE *get_db_connect(SQL_CONN_POOL *sp)
{
  //获取一个未使用的连接，用随机值访问index，保证每次访问每个节点的概率基本相同
  int start_index = 0, index = 0, i;
  int ping_res;

  if (sp->shutdown == 1)
  {
     return NULL;
  }

  srand((int)time(0)); //根据当前时间生成随机数
  start_index = rand() % sp->pool_number; //访问的开始地址

  for (i=0; i < sp->pool_number; i++)
  {
    index = (start_index + i) % sp->pool_number;

    if (!pthread_mutex_trylock(&sp->sql_pool[index].lock))
    {
       if (DB_DISCONN == sp->sql_pool[index].sql_state)
       {
          //重新连接
           if (0 != create_db_connect(sp, &(sp->sql_pool[index])))
           {
               //重新连接失败
               release_node(sp, &(sp->sql_pool[index]));
               continue;
           }
       }
       //检查服务器是否关闭了连接
       ping_res = mysql_ping(sp->sql_pool[index].mysql_sock);
       if (0 != ping_res)
       {
         printf("mysql ping error.\n");
         sp->sql_pool[index].sql_state = DB_DISCONN;
         release_node(sp, &(sp->sql_pool[index]));
       }
       else
       {
         sp->sql_pool[index].used = 1;
         sp->busy_number++;//被获取的数量增1
         break ;  //只需要一个节点
       }
    }
  }

  if (i == sp->pool_number)
  {
    return NULL;
  }
  else
  {
    return &(sp->sql_pool[index]);
  }

}

/*归回连接*/
void release_node(SQL_CONN_POOL *sp, SQL_NODE *node)
{
  node->used = 0;
  sp->busy_number--;
  pthread_mutex_unlock(&node->lock);
}


/*用户注册插入数据*/
int  mysql_insert(SQL_CONN_POOL *sp, const char* name, const char* salt, 
                  const char* cryptpasswd, const char* pwd){

    //获得一个数据库连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;

    //插入数据
    char q[512] = {0};

    //数据安全存储
    char name_esc[128];
    char salt_esc[128];
    char cryptpasswd_esc[128];
    char pwd_esc[128];
    mysql_real_escape_string(&conn, name_esc, name, strlen(name));
    mysql_real_escape_string(&conn, salt_esc, salt, strlen(salt));
    mysql_real_escape_string(&conn, cryptpasswd_esc, cryptpasswd, strlen(cryptpasswd));
    mysql_real_escape_string(&conn, pwd_esc, pwd, strlen(pwd));
    
    snprintf(q, sizeof(q),
             "INSERT INTO user_info (username, salt, cryptpasswd, pwd) VALUES ('%s', '%s', '%s', '%s');",
             name_esc, salt_esc, cryptpasswd_esc, pwd_esc);

    
    int ret = mysql_query(&conn, q);
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        //是否成功
        int rows = mysql_affected_rows(&conn);
        printf("Query OK, %d row affected.\n", rows);
        printf("INSERT SUCCESS.\n");
    }

    //归还连接
    release_node(sp, node);

    return 0;
}

/*查询salt值 */
int mysql_select_salt(SQL_CONN_POOL* sp, const char* username, char* result){
    //获得一个数据库连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;

    //拼接
    char q[512] = {0};
    char name_esc[128] = {0};
    mysql_real_escape_string(&conn, name_esc, username, strlen(username));
    snprintf(q, sizeof(q),
             "select salt from user_info where username = '%s';", name_esc);

    //查询语句
    int ret = mysql_real_query(&conn, q, strlen(q));
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        //结果
        MYSQL_RES* res = mysql_store_result(&conn);
        if(res == NULL){
            printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        }else{
            MYSQL_ROW row = NULL;
            //获得结果
            row = mysql_fetch_row(res);
            strncpy(result, row[0], strlen(row[0]));
        }
        mysql_free_result(res);
    }

    //归还连接
    release_node(sp, node);
    return 0;
}

/*查询cryptpasswd值 */
int mysql_select_crypt(SQL_CONN_POOL* sp, const char* username, char* result){
    //获得一个数据库连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;


    //拼接
    char q[512] = {0};
    char name_esc[128] = {0};
    mysql_real_escape_string(&conn, name_esc, username, strlen(username));
    snprintf(q, sizeof(q),
             "select cryptpasswd from user_info where username = '%s';", name_esc);

    //查询语句
    int ret = mysql_real_query(&conn, q, strlen(q));
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        //结果
        MYSQL_RES* res = mysql_store_result(&conn);
        if(res == NULL){
            printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        }else{
            MYSQL_ROW row = NULL;
            //获得结果
            row = mysql_fetch_row(res);
            strncpy(result, row[0], strlen(row[0]));
        }
        mysql_free_result(res);
    }

    //归还连接
    release_node(sp, node);
    return 0;
}

/*查询path_id值 */
int mysql_select_pwd(SQL_CONN_POOL* sp, const char* username, int* uid, int* path_id){

    //获得一个数据库连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;

    //拼接
    char q[512] = {0};
    char name_esc[128] = {0};
    mysql_real_escape_string(&conn, name_esc, username, strlen(username));
    snprintf(q, sizeof(q),
             "select uid,path_id from user_info where username = '%s';", name_esc);

    //查询语句
    int ret = mysql_real_query(&conn, q, strlen(q));
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        //结果
        MYSQL_RES* res = mysql_store_result(&conn);
        if(res == NULL){
            printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        }else{
            MYSQL_ROW row = NULL;
            //获得结果
            row = mysql_fetch_row(res);
            *uid = atoi(row[0]);
            *path_id = atoi(row[1]);
        }
        mysql_free_result(res);
        
    }
    //归还连接
    release_node(sp, node);
    return 0;
}

/*更新pwd(目录)*/
int mysql_update_pwd(SQL_CONN_POOL* sp, const char* name, const char* pwd){
    //获得一个数据库连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;

    char q[512] = {0};
    char name_esc[128] = {0};
    char pwd_esc[128] = {0};
    //数据安全
    mysql_real_escape_string(&conn, name_esc, name, strlen(name));
    mysql_real_escape_string(&conn, pwd_esc, pwd, strlen(pwd));
    
    //查询语句
    snprintf(q, sizeof(q),
             "update user_info set pwd = '%s' where username = '%s';", 
             pwd_esc, name_esc);

    int ret = mysql_query(&conn, q);
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        int rows = mysql_affected_rows(&conn);
        printf("Query OK, %d row affected.\n", rows);
        printf("UPDAT SUCCESS.\n");
    }

    //归还连接
    release_node(sp, node);

    return 0;
}


//判断用户名是否存在
int isUser(SQL_CONN_POOL* sp, const char* name){
    //获得一个数据库连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;

    //数据安全
    char q[512] = {0};
    char name_esc[128] = {0};
    mysql_real_escape_string(&conn, name_esc, name, strlen(name));

    //查询语句
    snprintf(q, sizeof(q), "SELECT COUNT(*) FROM user_info WHERE username = '%s';", name_esc);
    int result = 0;
    q[strlen(q)-1] = '\0';

    //查询语句
    int ret = mysql_real_query(&conn, q, strlen(q));
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return -1;
    }else{
        //结果
        MYSQL_RES* res = mysql_store_result(&conn);
        if(res == NULL){
            printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        }else{
            MYSQL_ROW row = NULL;
            //获得结果
            row = mysql_fetch_row(res);
            result = atoi(row[0]);
        }
        mysql_free_result(res);
    }

    //归还连接
    release_node(sp, node);
    printf("result= %d\n", result);
    return result;
}

/*登录成功后获取file信息*/
int login_getfile(SQL_CONN_POOL* sp, const char* name, file_t* file){
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;

    //数据安全
    char name_esc[32] = {0};
    mysql_real_escape_string(&conn, name_esc, name, strlen(name));
    
    //拼接语句
    char q[512] = {0};
    snprintf(q, sizeof(q), " select * \
                            from virtual_file \
                            where parent_id = 0 and owner_id = (select uid \
                                                                from user_info \
                                                                where username = '%s');", name_esc);

    //查询
    int ret = mysql_real_query(&conn, q, strlen(q));
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        MYSQL_RES* res = mysql_store_result(&conn);
        if(res == NULL){
            printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
            return EXIT_FAILURE;
        }else{
            int culms = mysql_num_fields(res);
            printf("rows:%d\n", culms);

            MYSQL_ROW row = NULL;
            while((row = mysql_fetch_row(res)) != NULL){
                for(int i = 0; i < culms; i++){
                    if(i == 0){
                        file->vfb_id = atoi(row[i]);
                    }
                    else if(i == 1){
                        file->parent_id = atoi(row[i]);
                    }
                    else if(i == 2){
                        strcpy(file->file_name, row[i]);
                    }
                    else if(i == 3){
                        file->owner_id = atoi(row[i]);
                    }
                    else if(i == 4){
                        strcpy(file->hash_val, row[i]);
                    }
                    else if(i == 5){
                        file->file_size = atol(row[i]);
                    }
                    else if(i == 6){
                        file->fileType = row[i][0];
                    }
                    else if(i == 7){
                        strcpy(file->all_path, row[i]);
                        
                    }
                }
            } 
        }
        mysql_free_result(res);
    }

    release_node(sp, node);
    return 0;
}

/*获取当前目录的id 作为创建新目录或文件的parent_id*/
int mkdir_get_dir_id(SQL_CONN_POOL* sp, const char* owner, int* uid, int* path_id){

    //获取连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;

    //数据安全
    char owner_esc[128] = {0};
    mysql_real_escape_string(&conn, owner_esc, owner, strlen(owner));

    char q[512] = {0};
    snprintf(q, sizeof(q), "select uid, path_id \
                            from user_info\
                            where username = '%s';", owner_esc); 
    //查询
    int ret = mysql_real_query(&conn, q, strlen(q));
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        MYSQL_RES* res = mysql_store_result(&conn);
        if(res == NULL){
            printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
            return EXIT_FAILURE;
        }else{
            MYSQL_ROW row = mysql_fetch_row(res);
            *uid = atoi(row[0]);
            *path_id = atoi(row[1]);
        }
        mysql_free_result(res);
    }
    release_node(sp, node);
    return 0;
}

/*获取当前目录完整路径pwd*/
int get_pwd(SQL_CONN_POOL* sp, const int vfb_id, const int owner_id, char* pwd){
    
    //获得连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;
    

    char q[512] ={0};
    sprintf(q, "select path from virtual_file where vfb_id = %d and owner_id = %d and type = 'd';", vfb_id, owner_id);

    int ret = mysql_real_query(&conn, q, strlen(q));
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        MYSQL_RES* res = mysql_store_result(&conn);
        if(res == NULL){
            printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
            return EXIT_FAILURE;
        }else{
            MYSQL_ROW row = mysql_fetch_row(res);
            strcpy(pwd, row[0]);
        }
        mysql_free_result(res);

    }

    release_node(sp, node);
    return 0;
}

/*创建新目录，插入virtual_file*/
int insert_virtual_file(SQL_CONN_POOL* sp, const int parent_id, const char* filename, const int owner_id, 
                                     const char* hash_val, const int filesize, const char type, char* path){

    //获得连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;

    if(type == 'd'){
        sprintf(path,"%s/%s", path, filename);
    }

    //拼接语句
    char q[512] = {0};
    snprintf(q, sizeof(q), "insert into virtual_file(parent_id, filename, owner_id, hash_val, filesize, type, path)\
                            values(%d, '%s', %d, '%s', %d, '%c', '%s');", parent_id, filename, owner_id, hash_val, filesize, type, path);
    int ret = mysql_query(&conn, q);
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        //是否成功
        int rows = mysql_affected_rows(&conn);
        printf("Query OK, %d row affected.\n", rows);
        printf("INSERT SUCCESS.\n");
    }

    //归还连接
    release_node(sp, node);

    return 0;

}

/*判断virtual_file表中是否存在该文件*/
int isExist_virtual_file(SQL_CONN_POOL* sp, const char* filename, const int parent_id, const int owner_id, const char type){
    int exist_flag = -1;
    //获得连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;
    

    char q[512] ={0};
    sprintf(q, "select count(*) from virtual_file \
                where owner_id = %d and parent_id = %d \
                and type = '%c' and filename = '%s';", owner_id, parent_id, type, filename);
    

    int ret = mysql_real_query(&conn, q, strlen(q));
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        MYSQL_RES* res = mysql_store_result(&conn);
        if(res == NULL){
            printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
            return EXIT_FAILURE;
        }else{
            MYSQL_ROW row = mysql_fetch_row(res);
            exist_flag = atoi(row[0]);
        }
        mysql_free_result(res);
    }

    release_node(sp, node);
    return exist_flag;

}

/*cd 目录切换，update，user_info中的path_id*/
int cd_dir(SQL_CONN_POOL* sp, const int parent_id, const int uid, const char* filename){
    //获得连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;

    //拼接语句
    char q[512] = {0};
    snprintf(q, sizeof(q), "update user_info\
                            set path_id = (select vfb_id\
                                           from virtual_file\
                                           where parent_id = %d and filename = '%s' and type = 'd')\
                                           where uid = %d;", parent_id, filename, uid);
    int ret = mysql_query(&conn, q);
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        //是否成功
        int rows = mysql_affected_rows(&conn);
        printf("Query OK, %d row affected.\n", rows);
        printf("UPDAT SUCCESS.\n");
    }

    //归还连接
    release_node(sp, node);

    return 0;
}

/*判断当前目录是否是根目录*/
int isRoot(SQL_CONN_POOL* sp, const int uid, const int path_id, int* parent_id){
    //获得连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;
    

    char q[512] ={0};
    sprintf(q, "select parent_id from virtual_file where vfb_id = %d and owner_id = %d and type = 'd';", path_id, uid);

    int ret = mysql_real_query(&conn, q, strlen(q));
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        MYSQL_RES* res = mysql_store_result(&conn);
        if(res == NULL){
            printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
            return EXIT_FAILURE;
        }else{
            MYSQL_ROW row = mysql_fetch_row(res);
            *parent_id = atoi(row[0]);
        }
        mysql_free_result(res);
    }

    release_node(sp, node);
    return 0;
}

/*cd: 目录返回*/
int re_dir(SQL_CONN_POOL* sp, const int parent_id, const int uid){
    //获得连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;

    //拼接语句
    char q[512] = {0};
    snprintf(q, sizeof(q), "update user_info\
                            set path_id = %d\
                            where uid = %d;", parent_id, uid);
    int ret = mysql_query(&conn, q);
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        //是否成功
        int rows = mysql_affected_rows(&conn);
        printf("Query OK, %d row affected.\n", rows);
        printf("UPDAT SUCCESS.\n");
    }

    //归还连接
    release_node(sp, node);

    return 0;
}

/*插入global_file*/
int insert_global_file(SQL_CONN_POOL* sp, const char* file_hash, const char* file_name, const int filesize){
    //获得连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;

    printf("file_hash:%s\n", file_hash);

    //拼接语句
    char q[512] = {0};
    snprintf(q, sizeof(q), "insert into global_file\
                            values('%s', '%s', %d);", file_hash, file_name, filesize);
    int ret = mysql_query(&conn, q);
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        //是否成功
        int rows = mysql_affected_rows(&conn);
        printf("Query OK, %d row affected.\n", rows);
        printf("INSERT SUCCESS.\n");
    }

    //归还连接
    release_node(sp, node);

    return 0;
}

/*判断服务器是否存在该文件--查询global_file*/
int isExist_file(SQL_CONN_POOL* sp, const char* file_hash){
    int exist = -1;
    //获得连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;

    char file_hash_esc[128] = {0};
    mysql_real_escape_string(&conn, file_hash_esc, file_hash, strlen(file_hash));

    char q[512] = {0};
    snprintf(q, sizeof(q), "select count(*) from global_file where file_hash = '%s';", file_hash_esc);

    int ret = mysql_real_query(&conn, q, strlen(q));
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        MYSQL_RES* res = NULL;
        res = mysql_store_result(&conn);
        if(res == NULL){
            printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
            return EXIT_FAILURE;
        }else{
            MYSQL_ROW row = NULL;
            row = mysql_fetch_row(res);
            exist = atoi(row[0]);
        }
        mysql_free_result(res); 
    }

    release_node(sp, node);
    return exist;
}

/*ls--当前目录下所有的文件*/
int get_ls(SQL_CONN_POOL* sp, const int parent_id, const int owner_id, char* result){
    //获得连接
    SQL_NODE* node = get_db_connect(sp);
    MYSQL conn = node->fd;

    char q[512] = {0};
    snprintf(q, sizeof(q), "select filename from virtual_file where parent_id = %d and owner_id = %d;", parent_id, owner_id);

    int ret = mysql_real_query(&conn, q, strlen(q));
    if(ret){
        printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
        return EXIT_FAILURE;
    }else{
        MYSQL_RES* res = NULL;
        res = mysql_store_result(&conn);

        if(res == NULL){
            printf("%d:%s\n", mysql_errno(&conn), mysql_error(&conn));
            return EXIT_FAILURE;
        }else{
            MYSQL_ROW row = NULL;
            while((row = mysql_fetch_row(res)) != NULL){
                    strcat(result, row[0]);
                    strcat(result,"\t");
            }
        }
        mysql_free_result(res);
    }

    release_node(sp, node);
    return 0;
}
